/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dynamic;

import dynamic.Edge;
import dynamic.VSDynamic;
import dynamic.ViewNodeDyn;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import visualcbir.PnlView;
import visualcbir.View;
import visualcbir.ViewComposed;
import visualcbir.node.ViewNode;

/**
 *
 * @author sheila
 */
public class PnlViewDynamic extends PnlView implements Runnable, MouseListener, MouseMotionListener{

    Thread relaxer;
    boolean stress;
    boolean random;
    

    public PnlViewDynamic(View poView) {
        super(poView);
    }
    
    public PnlViewDynamic(){
        super();

        relaxer=new Thread(this);
        relaxer.start();
    }


     public void run() {
        Thread me = Thread.currentThread();
        ViewComposed view= (ViewComposed)super.getoView();

	while (relaxer == me) {
	    relax();
	    if (random && (Math.random() < 0.03)) {
		ViewNode n = (ViewNode) view.getView(((int)Math.random() * view.getNumViews()));
		if (!n.equals(view.getView(0))) {//se nao é a imagem de consulta
                    n.setCenterPoint((int)(n.getCenterPoint().x - 100*Math.random()-50),
                            (int)(n.getCenterPoint().y - (int)100*Math.random()-50));		  
		}		
	    }
	    try {
		Thread.sleep(100);
	    } catch (InterruptedException e) {
		break;
	    }
	}
    }

    synchronized void relax() {
        VSDynamic view= (VSDynamic)super.getoView();
	for (int i = 0 ; i < view.aLenEdges.size() ; i++) {
	    Edge e = view.aLenEdges.get(i);
	    double vx = e.getoNodeTo().getCenterPoint().x - e.getoNodeTo().getCenterPoint().x;
	    double vy = e.getoNodeTo().getCenterPoint().y - e.getoNodeFrom().getCenterPoint().y;
	    double len = Math.sqrt(vx * vx + vy * vy);
            len = (len == 0) ? .0001 : len;
	    double f = (view.aLenEdges.get(i).getLen() - len) / (len * 3);
	    double dx = f * vx;
	    double dy = f * vy;

	    e.getoNodeTo().dx += dx;
	    e.getoNodeTo().dy += dy;
	    e.getoNodeFrom().dx += -dx;
	    e.getoNodeFrom().dy += -dy;
	}

	for (int i = 0 ; i < view.getNumViews() ; i++) {
	    ViewNodeDyn n1 = (ViewNodeDyn) view.getView(i);
	    double dx = 0;
	    double dy = 0;

	    for (int j = 0 ; j < view.getNumViews() ; j++) {
		if (i == j) {
		    continue;
		}
		ViewNode n2 = (ViewNode)view.getView(j);
		double vx = n1.getCenterPoint().x - n2.getCenterPoint().x;
		double vy = n1.getCenterPoint().y - n2.getCenterPoint().y;
		double len = vx * vx + vy * vy;
		if (len == 0) {
		    dx += Math.random();
		    dy += Math.random();
		} else if (len < 100*100) {
		    dx += vx / len;
		    dy += vy / len;
		}
	    }
	    double dlen = dx * dx + dy * dy;
	    if (dlen > 0) {
		dlen = Math.sqrt(dlen) / 2;
		n1.dx += dx / dlen;
		n1.dy += dy / dlen;
	    }
	}

	Dimension d = getSize();
	for (int i = 0 ; i < view.getNumViews() ; i++) {
	    ViewNodeDyn n = (ViewNodeDyn)view.getView(i);
	    if (i!=0) {// (!n.fixed) o unico fixed é a imagem de consulta que esta sempre em 0

                int newx=(int) (n.getCenterPoint().x + Math.max(-5, Math.min(5, n.dx)));
                int newy=(int) (n.getCenterPoint().y + Math.max(-5, Math.min(5, n.dy)));
		
                n.setCenterPoint(newx, newy);
            }
            if (n.getCenterPoint().x < 0) {
                n.setCenterPointX(0);
            } else if (n.getCenterPoint().x > d.width) {
                n.setCenterPointX(d.width);
            }
            if (n.getCenterPoint().y < 0) {
                n.setCenterPointY(0);
            } else if (n.getCenterPoint().y > d.height) {
                n.setCenterPointY(d.height);
            }
	    n.dx /= 2;
	    n.dy /= 2;
	}
	repaint();
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mousePressed(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseExited(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}
